<template>
  <div class="map-app">
    <!-- 顶部标题栏 -->
    <header class="app-header">
      <h1><i class="icon-map"></i> 百度地图导航</h1>
    </header>

    <!-- 主内容区 -->
    <main class="app-main">
      <!-- 侧边控制面板 -->
      <div class="control-panel">
        <!-- 地址搜索卡片 -->
        <div class="control-card">
          <h2 class="card-title"><i class="icon-search"></i> 地址搜索</h2>
          <div class="search-group">
            <input
              v-model="searchQuery"
              placeholder="输入地址、POI或地标..."
              class="search-input"
              @keyup.enter="searchAddress"
            />
            <button @click="searchAddress" class="search-button">
              <i class="icon-search"></i>
            </button>
          </div>
        </div>

        <!-- 定位卡片 -->
        <div class="control-card">
          <h2 class="card-title"><i class="icon-location"></i> 我的位置</h2>
          <button @click="locateMe" class="locate-button">
            <i class="icon-location"></i> 获取当前位置
          </button>
          <div v-if="currentAddress" class="current-address">
            <i class="icon-pin"></i> {{ currentAddress }}
          </div>
        </div>

        <!-- 路线规划卡片 -->
        <div class="control-card">
          <h2 class="card-title"><i class="icon-route"></i> 路线规划</h2>
          <div class="input-group">
            <label><i class="icon-start"></i> 起点</label>
            <input v-model="start" placeholder="输入起点位置" class="route-input" />
          </div>
          <div class="input-group">
            <label><i class="icon-end"></i> 终点</label>
            <input v-model="end" placeholder="输入终点位置" class="route-input" />
          </div>
          <div class="mode-selector">
            <button
              v-for="modeOption in modeOptions"
              :key="modeOption.value"
              @click="mode = modeOption.value"
              :class="{ active: mode === modeOption.value }"
            >
              <i :class="modeOption.icon"></i> {{ modeOption.label }}
            </button>
          </div>
          <button @click="searchRoute" class="route-button">
            <i class="icon-navigation"></i> 开始导航
          </button>
        </div>

        <!-- 路线结果卡片 -->
        <div v-if="routeResult" class="control-card result-card">
          <h2 class="card-title"><i class="icon-info"></i> 路线信息</h2>
          <div class="result-item">
            <div class="result-icon"><i class="icon-distance"></i></div>
            <div class="result-content">
              <div class="result-label">距离</div>
              <div class="result-value">{{ routeResult.distance }}</div>
            </div>
          </div>
          <div class="result-item">
            <div class="result-icon"><i class="icon-time"></i></div>
            <div class="result-content">
              <div class="result-label">时间</div>
              <div class="result-value">{{ routeResult.duration }}</div>
            </div>
          </div>
          <div class="result-item">
            <div class="result-icon"><i class="icon-directions"></i></div>
            <div class="result-content">
              <div class="result-label">路线详情</div>
              <div class="result-directions">
                <ul>
                  <li v-for="(step, index) in routeSteps" :key="index">
                    {{ step.instruction }}
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 地图容器 -->
      <div id="map-container"></div>
    </main>
  </div>
</template>

<script>
export default {
  data() {
    return {
      BAIDU_AK: 'quLAJj8XHbmpZ35HV3IA4sPxSoxpVBhZ',
      searchQuery: '',
      start: '',
      end: '',
      currentAddress: '',
      mode: 'driving',
      routeResult: null,
      routeSteps: [],
      map: null,
      markers: [],
      routeOverlay: null,
      modeOptions: [
        { value: 'driving', label: '驾车', icon: 'icon-car' },
        { value: 'walking', label: '步行', icon: 'icon-walk' },
        { value: 'transit', label: '公交', icon: 'icon-bus' },
        { value: 'riding', label: '骑行', icon: 'icon-bike' }
      ],
      loading: false,
      errorMessage: ''
    }
  },
  mounted() {
    this.loadBaiduMap().then(() => {
      this.initMap()
    }).catch(error => {
      console.error('加载百度地图失败:', error)
      this.showToast('地图加载失败，请检查网络连接')
    })
  },
  methods: {
    async loadBaiduMap() {
      return new Promise((resolve, reject) => {
        if (window.BMap) return resolve()
        
        window.baiduMapInit = () => resolve()
        const script = document.createElement('script')
        script.src = `https://api.map.baidu.com/api?v=3.0&ak=${this.BAIDU_AK}&callback=baiduMapInit`
        script.onerror = () => reject(new Error('百度地图API加载失败'))
        document.head.appendChild(script)
      })
    },
    initMap() {
      this.map = new BMap.Map('map-container')
      this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 15)
      this.map.enableScrollWheelZoom()
      this.map.addControl(new BMap.NavigationControl({ anchor: BMAP_ANCHOR_TOP_LEFT }))
      this.map.addControl(new BMap.ScaleControl())
      
      this.geocoder = new BMap.Geocoder()
      this.geolocation = new BMap.Geolocation()
      this.localSearch = new BMap.LocalSearch(this.map, {
        renderOptions: { map: this.map, panel: null }
      })
    },
    searchAddress() {
      if (!this.searchQuery.trim()) {
        this.showToast('请输入搜索内容')
        return
      }
      
      this.clearMap()
      this.localSearch.search(this.searchQuery)
    },
    locateMe() {
      this.loading = true
      this.geolocation.getCurrentPosition(
        position => {
          this.loading = false
          if (position && position.point) {
            const point = position.point
            this.clearMap()
            this.addMarker(point, '我的位置', 'location')
            this.map.setCenter(point)
            
            this.geocoder.getLocation(point, rs => {
              if (rs) {
                this.currentAddress = rs.address
                this.start = rs.address
              } else {
                this.showToast('无法获取当前位置地址信息')
              }
            })
          } else {
            this.showToast('无法获取当前位置')
          }
        },
        error => {
          this.loading = false
          console.error('定位失败:', error)
          this.showToast(`定位失败: ${this.getLocationErrorMsg(error.code)}`)
        },
        { enableHighAccuracy: true, maximumAge: 60000 }
      )
    },
    getLocationErrorMsg(errorCode) {
      const errorMessages = {
        1: '位置服务被拒绝',
        2: '暂时获取不到位置信息',
        3: '获取位置信息超时',
        4: '未知错误'
      }
      return errorMessages[errorCode] || '未知错误'
    },
    async searchRoute() {
      if (!this.start.trim() || !this.end.trim()) {
        this.showToast('请输入起点和终点')
        return
      }
      
      this.clearMap()
      this.loading = true
      this.errorMessage = ''
      
      try {
        // 解析起点
        const startPt = await this.getPointAsync(this.start)
        if (!startPt) {
          throw new Error('起点解析失败')
        }
        
        // 解析终点
        const endPt = await this.getPointAsync(this.end)
        if (!endPt) {
          throw new Error('终点解析失败')
        }
        
        this.addMarker(startPt, '起点', 'start')
        this.addMarker(endPt, '终点', 'end')
        this.map.setViewport([startPt, endPt])
        this.calculateRoute(startPt, endPt)
      } catch (error) {
        this.loading = false
        this.errorMessage = error.message
        this.showToast(error.message)
      }
    },
    getPointAsync(address) {
      return new Promise(resolve => {
        this.geocoder.getPoint(address, point => resolve(point), '北京市')
      })
    },
    calculateRoute(start, end) {
      let route
      
      switch (this.mode) {
        case 'driving':
          route = new BMap.DrivingRoute(this.map, {
            renderOptions: { map: this.map, autoViewport: true },
            onSearchComplete: this.handleRouteComplete,
            onError: this.handleRouteError
          })
          break
        case 'walking':
          route = new BMap.WalkingRoute(this.map, {
            renderOptions: { map: this.map, autoViewport: true },
            onSearchComplete: this.handleRouteComplete,
            onError: this.handleRouteError
          })
          break
        case 'transit':
          route = new BMap.TransitRoute(this.map, {
            renderOptions: { map: this.map, autoViewport: true },
            onSearchComplete: this.handleRouteComplete,
            onError: this.handleRouteError
          })
          break
        case 'riding':
          route = new BMap.RidingRoute(this.map, {
            renderOptions: { map: this.map, autoViewport: true },
            onSearchComplete: this.handleRouteComplete,
            onError: this.handleRouteError
          })
          break
      }
      
      route.search(start, end)
    },
    handleRouteComplete(results) {
      this.loading = false
      if (results && results.getNumPlans && results.getNumPlans() > 0) {
        const plan = results.getPlan(0)
        this.setRouteResult(plan)
        this.parseRouteSteps(plan)
      } else {
        this.showToast('未找到可行路线')
      }
    },
    handleRouteError(error) {
      this.loading = false
      console.error('路线规划错误:', error)
      const errorMessages = {
        100: '起终点校验失败',
        101: '起终点解析失败',
        102: '检索失败',
        103: '参数错误',
        104: '服务器内部错误',
        105: '服务请求超时',
        106: '服务繁忙'
      }
      const errorMessage = errorMessages[error] || '路线规划出错'
      this.showToast(errorMessage)
    },
    addMarker(point, title, type = 'default') {
      const marker = new BMap.Marker(point)
      
      // 根据类型设置不同颜色
      if (type === 'location') {
        const icon = new BMap.Icon(
          'https://api.map.baidu.com/images/markers.png',
          new BMap.Size(23, 25),
          { offset: new BMap.Size(10, 25), imageOffset: new BMap.Size(0, -200) }
        )
        marker.setIcon(icon)
        marker.setAnimation(BMAP_ANIMATION_BOUNCE)
      } else if (type === 'start') {
        const icon = new BMap.Icon(
          'https://api.map.baidu.com/images/markers.png',
          new BMap.Size(23, 25),
          { offset: new BMap.Size(10, 25), imageOffset: new BMap.Size(0, 0) }
        )
        marker.setIcon(icon)
      } else if (type === 'end') {
        const icon = new BMap.Icon(
          'https://api.map.baidu.com/images/markers.png',
          new BMap.Size(23, 25),
          { offset: new BMap.Size(10, 25), imageOffset: new BMap.Size(0, -250) }
        )
        marker.setIcon(icon)
      }
      
      this.map.addOverlay(marker)
      this.markers.push(marker)
      
      const label = new BMap.Label(title, {
        position: point,
        offset: new BMap.Size(20, -10)
      })
      marker.setLabel(label)
    },
    clearMap() {
      this.clearMarkers()
      this.clearRoute()
      this.routeResult = null
      this.routeSteps = []
    },
    clearMarkers() {
      this.markers.forEach(marker => {
        this.map.removeOverlay(marker)
      })
      this.markers = []
    },
    clearRoute() {
      if (this.routeOverlay) {
        this.map.removeOverlay(this.routeOverlay)
        this.routeOverlay = null
      }
    },
    setRouteResult(plan) {
      this.routeResult = {
        distance: plan.getDistance(true),
        duration: plan.getDuration(true)
      }
    },
    parseRouteSteps(plan) {
      this.routeSteps = []
      if (!plan || !plan.getNumRoutes) return
      
      const route = plan.getRoute(0)
      if (!route || !route.getNumSteps) return
      
      for (let i = 0; i < route.getNumSteps(); i++) {
        const step = route.getStep(i)
        this.routeSteps.push({
          instruction: step.getDescription(),
          distance: step.getDistance ? step.getDistance() : 0
        })
      }
    },
    showToast(message) {
      // 简单的提示效果
      const toast = document.createElement('div')
      toast.className = 'toast-message'
      toast.textContent = message
      document.body.appendChild(toast)
      
      setTimeout(() => {
        toast.classList.add('fade-out')
        setTimeout(() => {
          document.body.removeChild(toast)
        }, 300)
      }, 2000)
    }
  }
}
</script>

<style>
/* 基础样式 */
:root {
  --primary-color: #1890ff;
  --secondary-color: #52c41a;
  --text-color: #333;
  --text-light: #666;
  --border-color: #e8e8e8;
  --card-bg: #fff;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
  color: var(--text-color);
}

/* 图标字体 */
@font-face {
  font-family: 'iconfont';
  src: url('//at.alicdn.com/t/font_1234567_abcdefghijk.woff2') format('woff2'),
       url('//at.alicdn.com/t/font_1234567_abcdefghijk.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-map:before { content: "\e61a"; }
.icon-search:before { content: "\e65c"; }
.icon-location:before { content: "\e61e"; }
.icon-pin:before { content: "\e61f"; }
.icon-route:before { content: "\e620"; }
.icon-start:before { content: "\e621"; }
.icon-end:before { content: "\e622"; }
.icon-car:before { content: "\e623"; }
.icon-walk:before { content: "\e624"; }
.icon-bus:before { content: "\e625"; }
.icon-bike:before { content: "\e626"; }
.icon-navigation:before { content: "\e627"; }
.icon-info:before { content: "\e628"; }
.icon-distance:before { content: "\e629"; }
.icon-time:before { content: "\e62a"; }
.icon-directions:before { content: "\e62b"; }

/* 应用布局 */
.map-app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #f5f5f5;
}

.app-header {
  padding: 16px 24px;
  background: var(--primary-color);
  color: white;
  box-shadow: var(--shadow);
}

.app-header h1 {
  font-size: 20px;
  font-weight: 500;
  display: flex;
  align-items: center;
}

.app-header h1 i {
  margin-right: 8px;
  font-size: 24px;
}

.app-main {
  display: flex;
  flex: 1;
  overflow: hidden;
}

/* 控制面板 */
.control-panel {
  width: 320px;
  padding: 16px;
  background: white;
  overflow-y: auto;
  border-right: 1px solid var(--border-color);
}

.control-card {
  background: var(--card-bg);
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
  box-shadow: var(--shadow);
}

.card-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  color: var(--text-color);
}

.card-title i {
  margin-right: 8px;
  color: var(--primary-color);
}

/* 搜索框 */
.search-group {
  display: flex;
  margin-bottom: 8px;
}

.search-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 4px 0 0 4px;
  font-size: 14px;
  outline: none;
  transition: border 0.3s;
}

.search-input:focus {
  border-color: var(--primary-color);
}

.search-button {
  padding: 0 16px;
  background: var(--primary-color);
  color: white;
  border: none;
  border-radius: 0 4px 4px 0;
  cursor: pointer;
  transition: background 0.3s;
}

.search-button:hover {
  background: #40a9ff;
}

.search-button i {
  font-size: 18px;
}

/* 定位按钮 */
.locate-button {
  width: 100%;
  padding: 10px;
  background: var(--secondary-color);
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  margin-bottom: 12px;
  transition: background 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.locate-button:hover {
  background: #73d13d;
}

.locate-button i {
  margin-right: 6px;
}

.current-address {
  font-size: 13px;
  color: var(--text-light);
  padding: 8px;
  background: #f9f9f9;
  border-radius: 4px;
  display: flex;
  align-items: center;
}

.current-address i {
  margin-right: 6px;
  color: var(--secondary-color);
}

/* 路线输入 */
.input-group {
  margin-bottom: 12px;
}

.input-group label {
  display: block;
  font-size: 13px;
  color: var(--text-light);
  margin-bottom: 4px;
  display: flex;
  align-items: center;
}

.input-group label i {
  margin-right: 6px;
  font-size: 14px;
}

.route-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  font-size: 14px;
}

.route-input:focus {
  border-color: var(--primary-color);
}

/* 交通方式选择 */
.mode-selector {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 12px 0;
}

.mode-selector button {
  padding: 8px;
  background: white;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
}

.mode-selector button i {
  margin-right: 4px;
}

.mode-selector button.active {
  background: var(--primary-color);
  color: white;
  border-color: var(--primary-color);
}

/* 路线按钮 */
.route-button {
  width: 100%;
  padding: 12px;
  background: var(--primary-color);
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: background 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.route-button:hover {
  background: #40a9ff;
}

.route-button i {
  margin-right: 8px;
}

/* 路线结果 */
.result-card {
  background: #f9f9f9;
}

.result-item {
  display: flex;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px dashed var(--border-color);
}

.result-item:last-child {
  border-bottom: none;
}

.result-icon {
  width: 32px;
  height: 32px;
  background: var(--primary-color);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
}

.result-icon i {
  font-size: 16px;
}

.result-content {
  flex: 1;
}

.result-label {
  font-size: 12px;
  color: var(--text-light);
  margin-bottom: 2px;
}

.result-value {
  font-size: 15px;
  font-weight: 500;
}

.result-directions {
  margin-top: 8px;
}

.result-directions ul {
  list-style-type: none;
  max-height: 200px;
  overflow-y: auto;
}

.result-directions li {
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px solid #eee;
}

.result-directions li:last-child {
  border-bottom: none;
}

/* 地图容器 */
#map-container {
  flex: 1;
  background: #e8e8e8;
}

/* 提示消息 */
.toast-message {
  position: fixed;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px 20px;
  border-radius: 4px;
  font-size: 14px;
  z-index: 1000;
  animation: fade-in 0.3s;
}

.toast-message.fade-out {
  animation: fade-out 0.3s;
}

@keyframes fade-in {
  from { opacity: 0; bottom: 20px; }
  to { opacity: 1; bottom: 30px; }
}

@keyframes fade-out {
  from { opacity: 1; bottom: 30px; }
  to { opacity: 0; bottom: 20px; }
}

/* 加载中样式 */
.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.loading-spinner {
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-left-color: var(--primary-color);
  border-radius: 50%;
  width: 36px;
  height: 36px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .app-main {
    flex-direction: column;
  }
  
  .control-panel {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--border-color);
    overflow-x: auto;
    display: flex;
    padding: 12px;
  }
  
  .control-card {
    min-width: 280px;
    margin-right: 12px;
    margin-bottom: 0;
  }
  
  #map-container {
    height: 60vh;
  }
}
</style>  